package com.xinchuang.service.targetSystem.Impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.xinchuang.common.Result;
import com.xinchuang.common.ResultUtil;
import com.xinchuang.entity.target.TargetBaseData;
import com.xinchuang.entity.targetSystem.AirPlane;
import com.xinchuang.entity.targetSystem.system.SystemsRelation;
import com.xinchuang.entity.targetSystem.target.TargetData;
import com.xinchuang.entity.targetSystem.target.TargetSubMsgTable;
import com.xinchuang.entity.targetSystem.target.TargetSubRelationTable;
import com.xinchuang.mapper.targetSystem.SystemsRelationMapper;
import com.xinchuang.mapper.targetSystem.TargetMapper;
import com.xinchuang.service.RedisUseService;
import com.xinchuang.service.target.TargetBaseDataService;
import com.xinchuang.service.targetSystem.AirPlaneService;
import com.xinchuang.service.targetSystem.FeatureService;
import com.xinchuang.service.targetSystem.TargetService;
import com.xinchuang.service.targetSystem.target.TargetSubMsgTableService;
import com.xinchuang.service.targetSystem.target.TargetSubRelationTableService;
import com.xinchuang.util.Area;
import com.xinchuang.util.FileElseUtil;
import com.xinchuang.util.LngLatUtil;
import com.xinchuang.util.RedisUtil;
import com.xinchuang.utils.RedisName;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * TODO
 *
 * @author zkwczx
 * @version 1.0
 * @date 2024/3/12 11:25
 */
@Service
@RequiredArgsConstructor
public class FeatureServiceImpl implements FeatureService {

    private final TargetSubRelationTableService targetSubRelationTableService;

    private final AirPlaneService airPlaneService;

    private final TargetSubMsgTableService targetSubMsgTableService;

    private final SystemsRelationMapper systemsRelationMapper;

    private final TargetBaseDataService targetBaseDataService;

    private final TargetMapper targetMapper;

    private final RedisUseService redisUseService;

    private final RedisUtil redisUtil;

    @Override
    public Result targetSubPull(String targetId) {
        List<TargetSubRelationTable> targetSubPull = targetSubRelationTableService.getTargetSubPull(targetId);
        if (CollectionUtil.isEmpty(targetSubPull)) {
            return ResultUtil.success(ListUtil.empty());
        }
        List<Map<String, Object>> list = ListUtil.list(false);
        Map<String, Object> map;
        for (TargetSubRelationTable relationTable : targetSubPull) {
            map = new HashMap<>();
            map.put("label", relationTable.getSubName());
            map.put("value", relationTable.getSubId());
            list.add(map);
        }
        return ResultUtil.success(list);
    }

    @Override
    public Result systemsTargetPull(String sysId) {
        List<Map<String, Object>> list = ListUtil.list(false);
        List<String> targetList = redisUseService.getSystemsTargetList(sysId);
        targetList.forEach(targetId -> {
            Map<String, Object> map = new HashMap<>();
            map.put("label", FileElseUtil.getObjectToString(redisUtil.hget(RedisName.TARGET_BASE_DATA_ALL + "_" + targetId, "targetName")));
            map.put("value", targetId);
            list.add(map);
        });
        return ResultUtil.success(list);
    }

    @Override
    public Result targetFeatureAlgorithmOne(JSONObject json) {
        if (StringUtils.isBlank(json.getString("subId"))) {
            return ResultUtil.error(400, "请选择子目标");
        }
        if (CollectionUtil.isEmpty(json.getJSONArray("planeList"))) {
            return ResultUtil.error(400, "请选择预停机型");
        }
        TargetSubMsgTable one = targetSubMsgTableService.lambdaQuery()
                .eq(TargetSubMsgTable::getSubId, json.getString("subId"))
                .eq(TargetSubMsgTable::getKeyId, "plotinfoobj")
                .one();
        List<AirPlane> planeList = airPlaneService.lambdaQuery().in(AirPlane::getId, json.getJSONArray("planeList").toArray()).list();
        if (ObjectUtil.isNull(one) || StringUtils.isBlank(one.getKeyValue())) {
            return ResultUtil.error(400, "该子目标暂无标绘数据，暂时无法计算，请修改后重试");
        }
        double length = 0.0;
        double width = 0.0;
        for (AirPlane airPlane : planeList) {
            length += airPlane.getLength();
            width += airPlane.getWidth();
        }
        if (length <= 0 || width <= 0) {
            return ResultUtil.error(400, "飞机参数异常，请检查后重试");
        }
//        double area = Double.parseDouble(one.getKeyValue());
        double area = Area.getPosition(one.getKeyValue());
        int number = (int) (area / (length * width));
        StringBuffer sb = new StringBuffer();
        if (number == 0) {
            sb.append("所选机型无法停留在该子目标中");
        } else {
            for (AirPlane airPlane : planeList) {
                sb.append(airPlane.getName() + "可预停" + number + "架次;");
            }
        }
        Map<String, Object> resultMap = new HashMap<>(1);
        resultMap.put("analyzeData", sb.toString());
        return ResultUtil.success(resultMap);
    }

    @Override
    public Result systemFeatureAlgorithmOne(JSONObject json) {
        String sysId = json.getString("sysId");
        String targetId = json.getString("targetId");
        String planeId = json.getString("planeId");
        Integer oil = json.getInteger("oil");
        //计算可飞行的最远距离
        AirPlane plane = airPlaneService.getById(planeId);
        if (ObjectUtil.isNull(plane)) {
            return ResultUtil.error(400, "请选择机型");
        }
        if (null == oil) {
            return ResultUtil.error(400, "请输入加油次数");
        }
        double distance = plane.getDistance() * oil;
        //可到达的目的名称
        StringBuffer sb = new StringBuffer();
        TargetBaseData baseData = targetBaseDataService.getById(targetId);
        //获取体系下的所有目标
        List<TargetData> targetList = systemsRelationMapper.selectSystemTargetAll(sysId, "1");
        for (TargetData elseData : targetList) {
            if (elseData.getTargetId().equals(targetId)) {
                continue;
            }
            double v = LngLatUtil.getDistance(Double.parseDouble(baseData.getLon()), Double.parseDouble(baseData.getLat()), elseData.getLon(), elseData.getLat());
            if (distance >= v) {
                sb.append(plane.getName() + "可以抵达目标：（" + elseData.getTargetName() + ");");
            }
        }
        if (sb.length() == 0) {
            sb.append("暂无可到达的目标");
        }
        Map<String, Object> resultMap = new HashMap<>(1);
        resultMap.put("analyzeData", sb.toString());
        return ResultUtil.success(resultMap);
    }

    @Override
    public Result systemFeatureAlgorithmTwo(JSONObject json) {
        String sysId = json.getString("sysId");
        String source = json.getString("source");
        String target = json.getString("target");
        String planeId = json.getString("planeId");
        List<String> routeList = new ArrayList<>();
        //计算起点与终点的距离
        TargetData sourceTarget = targetMapper.findTargetOnly(source);
        TargetData targetTarget = targetMapper.findTargetOnly(target);
        double v = LngLatUtil.getDistance(sourceTarget.getLon(), sourceTarget.getLat(), targetTarget.getLon(), targetTarget.getLat());
        AirPlane plane = airPlaneService.getById(planeId);
        if (ObjectUtil.isNull(plane)) {
            return ResultUtil.error(400, "请选择机型");
        }
        if (plane.getDistance() >= v) {
            routeList.add(plane.getName() + "从" + sourceTarget.getTargetName()  + "出发可直达" + targetTarget.getTargetName() + ";");
        }
        //该体系所有目标
        List<TargetData> targetList = systemsRelationMapper.selectSystemTargetAll(sysId, "1");
        for (TargetData targetData : targetList) {
            if (targetData.getTargetId().equals(sourceTarget.getTargetId()) || targetData.getTargetId().equals(targetTarget.getTargetId())) {
                continue;
            }
            Set<String> set = new HashSet<>();
            set.add(sourceTarget.getTargetId());
            set.add(targetTarget.getTargetId());
            set.add(targetData.getTargetId());
            StringBuffer sb = new StringBuffer();
            if (getRoute(targetData, targetTarget, plane.getDistance(), targetList, sb, set)) {
                routeList.add(sb.toString());
            }
        }
        if (CollectionUtil.isEmpty(routeList)) {
            routeList.add("暂无可用方案");
        }
        StringBuffer buffer = new StringBuffer();
        for (String s : routeList) {
            buffer.append(s + "\n");
        }
        Map<String, Object> resultMap = new HashMap<>(1);
        resultMap.put("analyzeData", buffer.toString());
        return ResultUtil.success(resultMap);
    }

    private boolean getRoute(TargetData source, TargetData target, double distance, List<TargetData> targetList, StringBuffer sb, Set<String> set) {
        if (targetList.size() == set.size()) {
            return false;
        }
        for (TargetData targetData : targetList) {
            if (set.contains(targetData.getTargetId())) {
                continue;
            }
            //判断该目标与起点的距离
            double v1 = LngLatUtil.getDistance(source.getLon(), source.getLat(), targetData.getLon(), targetData.getLat());
            if (distance > v1) {
                //判断该目标与起点的距离
                double v2 = LngLatUtil.getDistance(target.getLon(), target.getLat(), targetData.getLon(), targetData.getLat());
                if (distance > v2) {
                    sb.append("需要在目标（" + targetData.getTargetName() + ")加一次油后可抵达目的地;");
                    return true;
                } else {
                    sb.append("需要在目标（" + targetData.getTargetName() + ")加一次油;");
                    set.add(targetData.getTargetId());
                    getRoute(targetData, target, distance, targetList, sb, set);
                }
            }
        }
        return false;
    }

    @Override
    public Result systemFeatureAlgorithmThree(JSONObject json) {
        String source = json.getString("source");
        String target = json.getString("target");
        Integer oil = json.getInteger("oil");
        //计算起点与终点的距离
        TargetBaseData sourceTarget = targetBaseDataService.getById(source);
        TargetBaseData targetTarget = targetBaseDataService.getById(target);
        double v = LngLatUtil.getDistance(Double.parseDouble(sourceTarget.getLon()), Double.parseDouble(sourceTarget.getLat()), Double.parseDouble(targetTarget.getLon()), Double.parseDouble(targetTarget.getLat()));
        //可用机型
        StringBuffer sb = new StringBuffer();
        List<AirPlane> airPlanes = airPlaneService.list();
        if (CollectionUtil.isEmpty(airPlanes)) {
            return ResultUtil.success("暂无可用机型");
        }
        if (null == oil) {
            return ResultUtil.error(400, "请输入加油次数");
        }
        for (AirPlane airPlane : airPlanes) {
            if (airPlane.getDistance() * oil >= v) {
                sb.append("可使用机型：（" + airPlane.getName() + ");");
            }
        }
        if (sb.length() == 0) {
            sb.append("暂无可用机型");
        }
        Map<String, Object> resultMap = new HashMap<>(1);
        resultMap.put("analyzeData", sb.toString());
        return ResultUtil.success(resultMap);
    }

}
